//	--------------------------------------------------------------------
//	Copyright(C) 2006,2007 Zhao Yukun. All rights reserved.
//	This file is a part of the Xeres system.
//	Xeres 2007
//	Contact : xeres.engine@gmail.com
//	$(reservedInfo)
//	$(reservedDeclaration)
//	--------------------------------------------------------------------
///	@file	<initors.h>
///	@path	~/src/engine/xcore/
///	@date	2008/03/25
///	@desc	Engine initializers.

#pragma once

#include "xeres.h"

#include "lib/utilities/callback.h"
#include "lib/utilities/dep_stages.h"

namespace xeres {

	/*! 
		\class	Initors
		\brief	Engine initializers & finalizers.
	*/
	class Initors
	{
	protected:
	
		/// \name Constructor & Destructor
		//@{

		/// \ctor
		Initors( void );

		/// \dtor
		~Initors( void );

		//@}

		/// \name Internal Manipulation
		//@{

		/*!
			\brief		The first frame update call.
						Performs all queued initialization.
		*/
		void FirstFrame( void );

		/*!
			\brief		Do all last cleanup works which must perform during update.
						The last frame update call, usually does not cleanup
						environments and global variables.
		*/
		void LastFrame( void );

		//@}

	public:

		/*
			\name Engine initialization & finalization

			Pre-defined stage:
			
				.			-	root stage, allocation & configuration.
				thread		-	initialize threads.
				device		-	prepare device related objects.
				renderer	-	prepare renderer before create resources.
				resource	-	prepare resources.
				final		-	run after all done.
			
			Notice thread/per-thread stage will run on all threads' initialization.
			
			There can be sub-stages, user can assign calls after or before specific sub-stage.
			
			some special stages
			
				./register/class		-	register basic class stage, extended class should register after it.
				./parallelized			-	initialize parallelize loop.
				./script				-	initialize script interpreter.
				thread/start/.			-	thread start stage, all threaded loader should run after it.
				thread/per-thread/.		-	per-thread execution stage.
		*/
		//@{

		/*!
			\brief		Queue an initializer to take some action after
						specific stage of initialization.
						Initializer is an functor callback.
						Notice some stage is executed on background thread.
		*/
		bool QueueInitializer( const WString& stage , const WString& dep , function<void(void)> init_call );

		/*!
			\brief		Queue a finalizer in finalization list, engine
						will take action when specific stages meets.
		*/
		bool QueueFinalizer( const WString& stage , const WString& dep , function<void(void)> fini_call );

		//@}

	private:

		/// \brief	Build default initors.
		void BuildDefault( void );

		// initialize stages
		dep_stages< function<void(void)> >	m_initStages;
		// finalize stages
		dep_stages< function<void(void)> >	m_finiStages;

		std::vector< function<void(void)> >		m_threadInitCallback;
		std::vector< function<void(void)> > 	m_threadFiniCallback;
	};

} // namespace xeres
